Charlottesville City Schools

ccs <- all_students %>%
  filter(division == "CCS")

ccs_average <- filter(all_students, grepl("CCS", division)) %>%
  group_by(year) %>%
  summarise(percent_above_10 = mean(percent_above_10))

ccs_labels <- ccs %>%
  filter(year == "2022 - 2023")

ccs_plt <- ggplot(ccs, aes(x = year, y = percent_above_10, group = school, color = school_level)) +
  geom_point(data = ccs_average, aes(x = year, y = percent_above_10), 
             inherit.aes = FALSE, color = "darkgrey") +
  geom_smooth(data = ccs_average, aes(x = year, y = percent_above_10, group = "average"), 
              color =  "darkgrey", size = 2) +
  geom_smooth(se=FALSE) +
  geom_point() +
  geom_text(data = ccs_labels, aes(label = school_short)) +
  annotate("label", x = "2022 - 2023", y = 20, label = "District Average", hjust = -.1,  
           color = "darkgrey", size = 3) +
  scale_y_continuous(labels = function(x) paste0(x, "%")) +
  scale_color_manual(values = ec_colors, breaks = c("Elementary", "Middle", "High")) +
  labs(y = "Rate of Chronic Absenteeism",
       x = "School Year",
       color = "School Level") +
  theme_bw() +
  theme(axis.text.x = element_text(angle = 25))

ggplotly(ccs_plt) %>%
  style(textposition = "right")

Albemarle County Public Schools

acs <- all_students %>%
  filter(division == "ACPS",
         school != "Community Lab School")

acs_average <- filter(all_students, grepl("ACPS", division)) %>%
  group_by(year) %>%
  summarise(percent_above_10 = mean(percent_above_10))

acs_labels <- acs %>%
  filter(year == "2022 - 2023")

ggplot(data = acs, aes(x = year, y = percent_above_10, group = school, color = school_level)) +
  geom_point(data = acs_average, aes(x = year, y = percent_above_10), 
             inherit.aes = FALSE, color = "darkgrey") +
  geom_smooth(data = acs_average, aes(x = year, y = percent_above_10, group = "average"), 
              color =  "darkgrey", size = 2) +
  geom_smooth(se=FALSE) +
  geom_point() +
  geom_label(data = acs_labels, aes(label = school_short), hjust = -.1, size = 3) +
  annotate("label", x = "2022 - 2023", y = 17.4, label = "District Average", hjust = -.1,  
           color = "darkgrey", size = 3) +
  facet_wrap(~factor(school_level, levels=c("Elementary","Middle","High"))) +
  scale_y_continuous(labels = function(x) paste0(x, "%")) +
  scale_color_manual(values = ec_colors, breaks = c("Elementary", "Middle", "High")) +
  labs(y = "Rate of Chronic Absenteeism",
       x = "School Year",
       color = "School Level") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 25))

Student Demographics

all_average <- all_students %>%
  group_by(year, division) %>%
  summarise(percent_above_10 = mean(percent_above_10))

demo_means <- chronic %>% 
  filter(subgroup != "All Students") %>%
  group_by(division, subgroup, year) %>%
  summarise(percent_above_10 = mean(percent_above_10))

demo_labels <- demo_means %>%
  filter(year == "2022 - 2023") %>%
  mutate(short = case_when(
    subgroup == "Economically Disadvantaged" ~ "Economically\nDisadvantaged",
    subgroup == "Students with Disabilities" ~ "Students with\nDisabilities",
    TRUE ~ subgroup))

avg_labels <- all_average %>%
  filter(year == "2022 - 2023")

avg_labels$label <- c("District Average", "District Average")

ggplot(demo_means, aes(x = year, y = percent_above_10, group = subgroup)) +
  geom_point(data = all_average, aes(x = year, y = percent_above_10), 
             inherit.aes = FALSE, color = "darkgrey") +
  geom_smooth(data = all_average, aes(x = year, y = percent_above_10, group = "average"), 
              color =  "darkgrey", size = 2) +
  geom_smooth(color = "black") +
  geom_point() +
  geom_label(data = demo_labels, aes(label = short), hjust = -.1, size = 2.5) +
  geom_label(data = avg_labels, aes(x = year, y = percent_above_10, label = label, group = "average"),
             hjust = -.1, size = 2.5, color = "darkgrey") +
  facet_wrap(~division) +
  scale_y_continuous(labels = function(x) paste0(x, "%")) +
  labs(x = "School Year",
       y = "Rate of Chronic Absenteeism") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 25))

Table

chronic %>%
  select(-school_level, -school_short) %>%
  reactable(
    defaultColDef = colDef(
      header = function(value)
        str_to_title(gsub("_", " ", value, fixed = TRUE)),
      align = "center",
      defaultSortOrder = "desc",
      headerStyle = list(background = "#f7f7f8")
    ),
    bordered = TRUE,
    highlight = TRUE
  )